const { Server } = require('socket.io');
const Message = require('./models/Message');
const jwt = require('jsonwebtoken');
const { roomMembers } = require('./controllers/room');
const { memberAcceipt } = require('./controllers/member');
const dayjs = require('dayjs');
const Member = require('./models/Member');
const Apply = require('./models/Apply');

/**
 * WebSocket
 */
const sockets = {};
const io = (server) => {
    const handler = new Server(server, { cors: true });
    handler.on('connection', (socket) => {
        // sockets[socket.userId] = socket.id;
        console.log('current sockets', sockets);
        const { token } = socket.handshake?.query;
        jwt.verify(token, process.env.APP_KEY, (err, member) => {
            if(err) {
                socket.disconnect();
                return;
            }
            socket.member = member;
            sockets[member.id] = socket.id;
        });
        console.log('socket connection success');

        socket.on('message', async (data) => {
            console.log('recive data: ', data);
            const {
                id: memoId,
                chatTypeId,
                messageTypeId,
                chatId,
                receiverId,
                content,
                member,
            } = data;
            const id = await Message.insert({
                senderId: member.id, receiverId, chatId, chatTypeId, messageTypeId, content: content.slice(0, 65355), status: 10,
            });
            console.log('message id', id);

            const message = {...data, id, status: 10, createdAt: dayjs().format('YYYY-MM-DD HH:mm:ss')}
            // 给自己发送
            console.log('to self', socket.id);
            socket.emit('message', {...message, memoId});
            // 群聊
            if(chatTypeId === 'room') {
                const members = await roomMembers(message.chatId);
                console.log('members', members);
                members.map(({memberId}) => {
                    console.log('to client', sockets?.[receiverId]);
                    socket.broadcast.to(sockets?.[memberId]).emit('message', message);
                });
            }
            else {
                console.log('to client', sockets?.[receiverId]);
                // 给对象发送
                socket.broadcast.to(sockets?.[receiverId]).emit('message', message);
            }
        });

        // 申请成为好友
        socket.on('apply', async (id) => {
            console.log('recive apply id: ', id);

            let apply = await Apply.where('receiverId', id).where('senderId', socket.member.id).first();
            console.log('send apply: ', apply);

            if(apply) {
                return;
            }
            apply = {
                receiverId: id,
                chatTypeId: 'person',
                senderId: socket.member.id,
                applyTypeId: 'friend',
                remark: '想和你成为朋友',
                status: 1,
            };
            const applyId = await Apply.insert(apply);
            apply.createdAt = dayjs().format('YYYY-MM-DD HH:mm:ss');
            const {token: _, password: __, ...sender} = await Member.findOne(apply.senderId);
            apply.sender = sender;
            const {token, password, ...receiver} = await Member.findOne(apply.receiverId);
            apply.receiver = receiver;
            // 推送消息
            socket.broadcast.to(sockets?.[id]).emit('apply', {...apply, id: applyId});
            socket.emit('apply', apply);
        });

        // 通过好友申请
        socket.on('accept', async (id) => {
            console.log('recive accept id: ', id);

            const apply = await memberAcceipt(id, socket.member);
            console.log('send accept: ', apply);

            // 推送消息
            socket.emit('accept', apply);

            if(apply.chatTypeId === 'person') {
                const message = {
                    senderId: socket.member.id, chatTypeId: 'person', receiverId: apply.senderId, chatId: apply.friend.chatId, messageTypeId: 'notice', content: '通过了好友申请', status: 10,
                }
                message.id = await Message.insert(message);
                message.createdAt = dayjs().format('YYYY-MM-DD HH:mm:ss');
                const {token, password, ...member} = await Member.findOne(socket.member.id);
                // 推送消息
                socket.broadcast.to(sockets?.[apply.senderId]).emit('accept', {...apply, senderId: member.id, friend: {...member, chatId: apply.friend.chatId}});
                socket.emit('message', message);
                socket.broadcast.to(sockets?.[apply.senderId]).emit('message', message);
            }
        });
    });

    handler.on('disconnection', (socket) => {
        console.log('socket disconnection success');
        delete sockets?.[socket.member.id];
    });
}

module.exports = io;